﻿using MQTTnet;
using MQTTnet.Client.Options;
using MQTTnet.Extensions.ManagedClient;
using MQTTnet.Protocol;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace MQTT.Client
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private IManagedMqttClient mqttClient;

        public MainWindow()
        {
            InitializeComponent();

            // 初始化Client
            mqttClient = new MqttFactory().CreateManagedMqttClient();

            mqttClient.UseDisconnectedHandler(ee =>
            {
                WriteLog(">>> 服务端断开连接");
            });

            mqttClient.UseApplicationMessageReceivedHandler(ee =>
            {
                WriteLog(">>> 收到消息");
                WriteLog($"+ Topic = {ee.ApplicationMessage.Topic}");

                try
                {
                    WriteLog($"+ PayLoad={Encoding.UTF8.GetString(ee.ApplicationMessage.Payload)}");
                }
                catch { }

                WriteLog($"+ Qos={ee.ApplicationMessage.QualityOfServiceLevel}");
                WriteLog($"+ Retain={ee.ApplicationMessage.Retain}");
                WriteLog("");
            });

            mqttClient.UseConnectedHandler(ee =>
            {
                WriteLog(">>> 连接到服务");
            });
        }

        public void WriteLog(string message)
        {
            if (!(txtRich.CheckAccess()))
            {
                this.Dispatcher.Invoke(() => WriteLog(message));
                return;
            }
            string strTime = "[" + System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "] ";
            txtRich.AppendText(strTime + message + "\r");

        }

        /// <summary>
        /// 连接
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnStart_Click(object sender, RoutedEventArgs e)
        {
            // 向服务端开放的端口进行服务请求
            var mqttClientOptions = new MqttClientOptionsBuilder()
                .WithClientId(this.tbClientId.Text) // 客户端ID
                .WithTcpServer(this.tbHostAddr.Text, int.Parse(this.tbHostPort.Text)) //ip:port
                .WithCredentials(this.tbUsername.Text, this.tbPassword.Text); // 连接的用户名和密码

            var options = new ManagedMqttClientOptionsBuilder()
                .WithAutoReconnectDelay(TimeSpan.FromSeconds(5)) // 断线5秒后重连
                .WithClientOptions(mqttClientOptions.Build())
                .Build();

            mqttClient.StartAsync(options);

        }

        /// <summary>
        /// 断开
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnStop_Click(object sender, RoutedEventArgs e)
        {
            mqttClient?.StopAsync();
        }

        /// <summary>
        /// 订阅
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void btnSubscribe_Click(object sender, RoutedEventArgs e)
        {
            // 检查Topic是否为空
            var topic = this.tbTopic.Text;
            // Qos Quality of Service 服务质量
            // MqttQualityOfServiceLevel.AtMostOnce:默认值
            await mqttClient.SubscribeAsync(topic,MqttQualityOfServiceLevel.AtLeastOnce);

        }

        /// <summary>
        /// 发布
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnPublish_Click(object sender, RoutedEventArgs e)
        {
            var topic = this.tbPubTopic.Text;
            var payload = this.tbContent.Text;

            // 检查一下相关数据的正确性
            // MqttQualityOfServiceLevel.AtMostOnce:默认值
            mqttClient.PublishAsync(topic, payload, MqttQualityOfServiceLevel.AtLeastOnce);

        }


    }
}
